/**
 * Author(s): xuming.Wong <xuming.Wong@gmail.com>
 */
#ifndef __PQ_Platform_H__
#define __PQ_Platform_H__

#include "PQCompiler.h"

#include <sys/types.h>
#include <assert.h>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include <fstream>

/** In order to avoid finger-aches :)
*/
typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned long ulong;


// Integer formats of fixed bit width
typedef unsigned int uint32;
typedef unsigned short uint16;
typedef unsigned char uint8;
typedef int int32;
typedef short int16;
typedef char int8;

// define uint64 type
#if COMPILER == COMPILER_MSVC
	typedef unsigned __int64 uint64;
	typedef __int64 int64;
#else
	typedef unsigned long long uint64;
	typedef long long int64;
#endif

//typedefs
typedef std::vector<std::string> StringVector;
typedef std::map<std::string,int> StringIntMap;

#if PLATFORM == PLATFORM_WINDOWS
#  define PQ_EXPORT __declspec(dllexport)
#  define PQ_IMPORT __cdecl
#else //PLATFORM != PLATFORM_WINDOWS
#  define PQ_EXPORT export
#  if defined(__APPLE_CC__) && defined(BIG_ENDIAN)
#    define PQ_IMPORT __attribute__ ((longcall))
#  elif defined(__x86_64__)
#    define PQ_IMPORT
#  else
#    define PQ_IMPORT __attribute__ ((cdecl))
#  endif //__APPLE_CC__ && BIG_ENDIAN
#endif //PLATFORM

#if PLATFORM == PLATFORM_WINDOWS
#  ifdef PQ_WIN32_DLL_IMPORT
#    define PQ_DLL_SPEC __declspec(dllimport)
#  else //!PQ_WIN32_DLL_IMPORT
#    ifdef PQ_WIND_DLL_EXPORT
#      define PQ_DLL_SPEC __declspec(dllexport)
#    else //!PQ_WIND_DLL_EXPORT
#      define PQ_DLL_SPEC
#    endif //PQ_WIND_DLL_EXPORT
#  endif //PQ_WIN32_DLL_IMPORT
#else //PLATFORM != PLATFORM_WINDOWS
#  define PQ_DLL_SPEC
#endif //PLATFORM

#if PLATFORM == PLATFORM_WINDOWS
#  define PQ_DLL_DECL __declspec(dllexport)
#  ifndef DECLSPEC_NORETURN
#    define DECLSPEC_NORETURN __declspec(noreturn)
#  endif //DECLSPEC_NORETURN
#else //PLATFORM != PLATFORM_WINDOWS
#  define PQ_DLL_DECL
#  define DECLSPEC_NORETURN
#endif //PLATFORM

#if !defined(DEBUG)
#  define PQ_INLINE inline
#else //DEBUG
#  if !defined(PQ_DEBUG)
#    define PQ_DEBUG
#  endif //PQ_DEBUG
#  define PQ_INLINE
#endif //!DEBUG

#if COMPILER == COMPILER_GNU
#  define ATTR_NORETURN __attribute__((noreturn))
#  define ATTR_PRINTF(F,V) __attribute__ ((format (printf, F, V)))
#else //COMPILER != COMPILER_GNU
#  define ATTR_NORETURN
#  define ATTR_PRINTF(F,V)
#endif //COMPILER == COMPILER_GNU


#if COMPILER != COMPILER_MSVC
typedef uint16      WORD;
typedef uint32      DWORD;
#endif //COMPILER

#if !defined(HANDLE)
typedef void *HANDLE;
#endif


typedef uint64 OBJECT_HANDLE;

#endif //PQ_DEFINE_H
